package com.itheima.putige.putige.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.itheima.putige.putige.common.BaseContext;
import com.itheima.putige.putige.common.CustomException;
import com.itheima.putige.putige.common.R;
import com.itheima.putige.putige.dto.EchartsDto;
import com.itheima.putige.putige.dto.OrderDto;
import com.itheima.putige.putige.entity.AddressBook;
import com.itheima.putige.putige.entity.OrderDetail;
import com.itheima.putige.putige.entity.Orders;
import com.itheima.putige.putige.entity.ShoppingCart;
import com.itheima.putige.putige.service.AddressBookService;
import com.itheima.putige.putige.service.OrderDetailService;
import com.itheima.putige.putige.service.OrderService;
import com.itheima.putige.putige.service.ShoppingCartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ClassName: OrderController
 * Description:
 * date: 2022/3/1 19:58
 *
 * @author zjf95
 * @since JDK 1.8
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    /**
    * Description:  提交订单
    * @author: zjf95
    * @date: 2022/3/2 9:59
    * @param:
    * @return:
    */
    /*@PostMapping("/submit")
    public R<String> submit(@RequestBody Orders orders){

        log.info("提交的订单：{}",orders);

        orderService.submit(orders);

        return R.success("提交订单成功");
    }*/
    /**
     * @Author 16372
     * @Descripted //TODO 提交订单并跳转支付页面
     * @Date 18:16 2022/3/2
     * @Param [orders]
     * @return com.itheima.putige.putige.common.R<com.itheima.putige.putige.entity.Orders>
     **/
    @PostMapping("/submit")
    public R<Orders> submit(@RequestBody Orders orders) {

        log.info("订单数据:{}", orders);
        orders.setStatus(1);    //待付款
        orderService.submit(orders);
        System.out.println("orders = " + orders);
        return R.success(orders);
    }


    /**
    * Description: 订单列表
    * @author: zjf95
    * @date: 2022/3/2 9:59
    * @param:
    * @return:
    */
    @GetMapping("/userPage")
    public R<Page> page(int page, int pageSize){

        //创建分页对象
        Page<Orders> ordersPage = new Page<>(page, pageSize);
        Page<OrderDto> orderDtoPage = new Page<>();

        //某个用户的订单
        Long currentId = BaseContext.getCurrentId();
        //Long currentId = (Long) request.getSession().getAttribute("user");

        log.info(currentId.toString());

        //根据用户名获取全部订单的条件设置
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId, currentId);
        queryWrapper.orderByDesc(Orders::getCheckoutTime);

        //根据条件查询分页
        orderService.page(ordersPage, queryWrapper);

        //将order的分页对象复制给orderDto的分页对象，除了数据意外的数据
        BeanUtils.copyProperties(ordersPage, orderDtoPage, "records");

        //获取order的分页对象中的实体数据
        List<Orders> records = ordersPage.getRecords();

        //将数据储存在orderDto的集合中
        List<OrderDto> orderDtoList = records.stream().map((item) -> {
            OrderDto orderDto = new OrderDto();

            //复制数据
            BeanUtils.copyProperties(item, orderDto);

            Long orderId = item.getId();

            //设置条件，根据订单编号来获取订单明细的条件
            LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderDetail::getOrderId, orderId);

            //根据订单编号来获取订单明细
            List<OrderDetail> list = orderDetailService.list(wrapper);

            //赋值给orderDto对象
            orderDto.setOrderDetails(list);

            return orderDto;
        }).collect(Collectors.toList());

        orderDtoPage.setRecords(orderDtoList);

        return R.success(orderDtoPage);
    }

    /**
    * Description:  商家的订单页
    * @author: zjf95
    * @date: 2022/3/2 10:09
    * @param:
    * @return:
    */
    @GetMapping("/page")
    public R<Page> getPage(int page, int pageSize, String number, String beginTime, String endTime){

        Page<Orders> orderPage = new Page<>(page,pageSize);
        Page<OrderDto> orderDtoPage = new Page<>();

        //Long userId = BaseContext.getCurrentId();

        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //queryWrapper.eq(Orders::getUserId,userId);
        queryWrapper.like(number != null , Orders::getNumber,number);
        queryWrapper.between(beginTime != null && endTime != null ,Orders::getOrderTime,beginTime,endTime);
        queryWrapper.orderByDesc(Orders::getCheckoutTime);
        orderService.page(orderPage,queryWrapper);

        BeanUtils.copyProperties(orderPage, orderDtoPage, "records");

        List<Orders> records = orderPage.getRecords();
        List<OrderDto> orderDtoList = records.stream().map((item) -> {
            OrderDto orderDto = new OrderDto();
            BeanUtils.copyProperties(item, orderDto);

            try {
                //设置用户名
                Long addressBookId = item.getAddressBookId();
                AddressBook addressBook = addressBookService.getById(addressBookId);
                orderDto.setUserName(addressBook.getConsignee());
            } catch (Exception e) {
                //throw new CustomException("数据库损坏,订单主体资料丢失");
            }

            return orderDto;
        }).collect(Collectors.toList());

        orderDtoPage.setRecords(orderDtoList);

        return R.success(orderDtoPage);

    }

    /**
    * Description:  修改订单状态
    * @author: zjf95
    * @date: 2022/3/2 10:21
    * @param:
    * @return:
    */
    @PutMapping
    public R<String> update(@RequestBody Orders orders) {
        log.info("修改的状态：{}" ,orders);

        orderService.updateById(orders);

        return R.success("修改订单状态成功");
    }

    /**
    * Description: 再来一单
    * @author: zjf95
    * @date: 2022/3/2 10:28
    * @param:
    * @return:
    */
    @PostMapping("/again")
    public R<List<ShoppingCart>> again(@RequestBody Orders orders){
        //1.在orderDetail表中查询订单明细
        //2.在购物车的表中删除现在购物车里面的菜品或套餐
        //3.将订单再次添加进去购物车中，返回购物车的数据

        // String number = orders.getNumber();
        Long ordersId = orders.getId();
        //在orders表中查出订单信息
        //Orders order = ordersService.getById(ordersId);

        Long userId = BaseContext.getCurrentId();
        LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderDetail::getOrderId, ordersId);

        // OrderDetail orderDetail = orderDetailService.getOne(queryWrapper);

        List<OrderDetail> orderDetails = orderDetailService.list(queryWrapper);
        List<ShoppingCart> shoppingCartList = orderDetails.stream().map((item) -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            shoppingCart.setNumber(item.getNumber());
            shoppingCart.setDishFlavor(item.getDishFlavor());
            shoppingCart.setUserId(userId);
            shoppingCart.setName(item.getName());
            shoppingCart.setImage(item.getImage());
            shoppingCart.setAmount(item.getAmount());
            shoppingCart.setDishId(item.getDishId());
            shoppingCart.setSetmealId(item.getSetmealId());
            shoppingCart.setCreateTime(LocalDateTime.now());
            return shoppingCart;
        }).collect(Collectors.toList());

        //shoppingCartService.save();
        //shoppingCartService
        LambdaQueryWrapper<ShoppingCart> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShoppingCart::getUserId, userId);
        shoppingCartService.remove(wrapper);

        shoppingCartService.saveBatch(shoppingCartList);

        return R.success(shoppingCartList);

    }

    @GetMapping("/echarts")
    public R<EchartsDto> getCont(String beginTime, String endTime){
        EchartsDto echartsDto = new EchartsDto();
        System.err.println("beginTime = " + beginTime);
        System.err.println("endTime = " + endTime);
        //构建查询条件
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(orders.amount) as sumAll")
                .lambda().between(beginTime != null && endTime != null, Orders::getOrderTime, beginTime, endTime);

        Orders orders = orderService.getOne(queryWrapper);
        //统计订单总金额
        echartsDto.setMoney(orders.getSumAll()==null? BigDecimal.valueOf(0) :orders.getSumAll());
        if (echartsDto.getMoney() == null){
            return R.error("目标时间段无订单");
        }
        //统计销售量
        List<OrderDetail> orderDetails = orderDetailService.selectJoinList(OrderDetail.class,
                new MPJLambdaWrapper<EchartsDto>()
                        .select(OrderDetail::getName)
                        .selectSum(OrderDetail::getNumber, "number")
                        .leftJoin(Orders.class, Orders::getId, OrderDetail::getOrderId)
                        .between(endTime != null,Orders::getOrderTime, beginTime, endTime)
                        .groupBy(OrderDetail::getDishId, OrderDetail::getSetmealId,OrderDetail::getName)
        );
        if (orderDetails != null){
            List<Map<String,Object>> echartData = new ArrayList<>();
            for (OrderDetail orderDetail : orderDetails) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("name",orderDetail.getName());
                map.put("value",orderDetail.getNumber());
                echartData.add(map);
            }
            echartsDto.setEcharts(echartData);
        }
        return R.success(echartsDto);
    }

}
